package com.agileai.portal.portlets.wcmlist;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.ProcessAction;
import javax.portlet.ReadOnlyException;
import javax.portlet.RenderMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ValidatorException;
import javax.servlet.http.HttpServletRequest;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.common.StringTemplateLoader;
import com.agileai.hotweb.domain.core.Profile;
import com.agileai.hotweb.domain.core.Resource;
import com.agileai.hotweb.domain.core.User;
import com.agileai.portal.bizmoduler.wcm.InfomationManage;
import com.agileai.portal.bizmoduler.wcm.KeyWordsTreeManage;
import com.agileai.portal.driver.GenericPotboyPortlet;
import com.agileai.portal.driver.common.PortletRequestHelper;
import com.agileai.portal.driver.common.PreferenceException;
import com.agileai.portal.driver.common.PreferencesHelper;
import com.agileai.portal.driver.common.PreferencesWrapper;
import com.agileai.portal.portlets.PortletCacheManager;
import com.agileai.util.DateUtil;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;

public class RelativeInfoGrid extends GenericPotboyPortlet {
	
	public static final class QueryParamKeys{
		public static String searchWord = "searchWord";
		public static String keyWordsId = "keyWordsId";
	}
	
	@RenderMode(name = "view")
	public void view(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletPreferences preferences =  PreferencesHelper.getPublicPreference(request);
		String templateId = preferences.getValue("templateId", null);
		String minHeight = preferences.getValue("minHeight", null);
		String sortPolicy = preferences.getValue("sortPolicy", null);
		String queryParamKey = preferences.getValue("queryParamKey", null);
		String infoLinkURL = preferences.getValue("infoLinkURL", null);
		
		String recCountPerPage = preferences.getValue("recCountPerPage",null);
		String mainNumCount = preferences.getValue("mainNumCount", null);
		String sideNumCount = preferences.getValue("sideNumCount", null);
		String maxCharNumber = preferences.getValue("maxCharNumber", "30");
		
		if (!StringUtil.isNullOrEmpty(templateId) && !StringUtil.isNullOrEmpty(sortPolicy) 
				&& !StringUtil.isNullOrEmpty(minHeight)
				&& !StringUtil.isNullOrEmpty(infoLinkURL)
				&& !StringUtil.isNullOrEmpty(recCountPerPage) 
				&& !StringUtil.isNullOrEmpty(mainNumCount) 
				&& !StringUtil.isNullOrEmpty(sideNumCount)
				&& !StringUtil.isNullOrEmpty(queryParamKey)
				){
			request.setAttribute("isSetting", "Y");
		}else{
			request.setAttribute("isSetting", "N");
		}
		
		String isSetting = (String)request.getAttribute("isSetting");
		if ("Y".equals(isSetting)){
			HttpServletRequest httpServletRequest = PortletRequestHelper.getRequestContext(request).getServletRequest();
			if (QueryParamKeys.keyWordsId.equals(queryParamKey)){
				String keyWordsId = httpServletRequest.getParameter(queryParamKey);
				if (!StringUtil.isNullOrEmpty(keyWordsId)){
					InfomationManage infomationManage = this.lookupService(InfomationManage.class);
					
					List<DataRow> tempRecords = infomationManage.findRelativeInfomationRecordsByKeyWordsId(keyWordsId, InfomationManage.InfoState.Published, sortPolicy);
					List<DataRow> records = this.getAuthedRecords(tempRecords, request);
					String urlPrefix = PortletCacheManager.buildDataURLPefix(request);
					InfomationsModel infoListModel = new InfomationsModel();
					try {
						String content = "";
						int recordsCount = 0;
						if (records != null && records.size() > 0){
							recordsCount = records.size();
							for (int i=0;i < recordsCount;i++){
								DataRow temp = records.get(i);
								DataRow row =  new DataRow();
								infoListModel.getRecordList().add(row);
								row.put("id",temp.stringValue("INFO_ID"));
								row.put("title",temp.stringValue("INFO_TITLE"));
								row.put("shortTitle",temp.stringValue("INFO_SHORTTITLE"));
								row.put("readCount",temp.stringValue("INFO_READ_COUNT"));
								Date date = (Date)temp.get("INFO_PUBLISH_TIME");
								row.put("publishTime",DateUtil.format(DateUtil.YYMMDDHHMI_HORIZONTAL, date));
							}
							
							StringWriter writer = new StringWriter();
							String tempateURL = urlPrefix+"/resource?PortletTemptProvider&actionType=retrieveContent&contentId="+templateId;
							String template = this.retrieveData(preferences, tempateURL);
							infoListModel.setInfoLinkURL(getURLPrefix(request)+infoLinkURL);
							KeyWordsTreeManage keyWordsTreeManage = this.lookupService(KeyWordsTreeManage.class);
							DataParam keyWordQueryParam = new DataParam("WORD_ID",keyWordsId);
							DataRow keyWordRow = keyWordsTreeManage.queryCurrentRecord(keyWordQueryParam);
							infoListModel.setKeyWordName(keyWordRow.stringValue("WORD_NAME"));
							
							generate(infoListModel, template, writer);
							content = writer.toString();
						}
						request.setAttribute("recordsCount",String.valueOf(recordsCount));
						request.setAttribute("content", content);
					} catch (Exception e) {
						logger.error(e.getLocalizedMessage(), e);
					}					
				}
			}
			else if (QueryParamKeys.searchWord.equals(queryParamKey)){
				String searchWord = httpServletRequest.getParameter(queryParamKey);
				if (!StringUtil.isNullOrEmpty(searchWord)){
					InfomationManage infomationManage = this.lookupService(InfomationManage.class);
					List<DataRow> tempRecords = infomationManage.findRelativeInfomationRecordsBysearchWord(searchWord, InfomationManage.InfoState.Published, sortPolicy);
					List<DataRow> records = this.getAuthedRecords(tempRecords, request);
					String urlPrefix = PortletCacheManager.buildDataURLPefix(request);
					InfomationsModel infoListModel = new InfomationsModel();
					try {
						infoListModel.setInfoLinkURL(getURLPrefix(request)+infoLinkURL);
						infoListModel.setSearchParam(searchWord);
						int recordsCount = 0;
						String content = "";
						if (records != null && records.size() > 0){
							StringWriter writer = new StringWriter();
							recordsCount = records.size();
							for (int i=0;i < recordsCount;i++){
								DataRow temp = records.get(i);
								DataRow row =  new DataRow();
								infoListModel.getRecordList().add(row);
								row.put("id",temp.stringValue("INFO_ID"));
								row.put("title",temp.stringValue("INFO_TITLE"));
								
								String shortTitle = temp.stringValue("INFO_SHORTTITLE");
								row.put("shortTitle",this.substring(shortTitle, maxCharNumber));
								
								row.put("readCount",temp.stringValue("INFO_READ_COUNT"));
								Date date = (Date)temp.get("INFO_PUBLISH_TIME");
								row.put("publishTime",DateUtil.format(DateUtil.YYMMDDHHMI_HORIZONTAL, date));
							}
							
							String tempateURL = urlPrefix+"/resource?PortletTemptProvider&actionType=retrieveContent&contentId="+templateId;
							String template = this.retrieveData(preferences, tempateURL);
							generate(infoListModel, template, writer);
							content = writer.toString();
						}
						request.setAttribute("recordsCount",String.valueOf(recordsCount));
						request.setAttribute("content",content);						
					} catch (Exception e) {
						logger.error(e.getLocalizedMessage(), e);
					}					
				}
				
			}
			request.setAttribute("recCountPerPage", recCountPerPage);
			request.setAttribute("minHeight", minHeight);
			request.setAttribute("mainNumCount", mainNumCount);
			request.setAttribute("sideNumCount", sideNumCount);
		}
		super.doView(request, response);
	}
	
	private String getURLPrefix(PortletRequest request){
		return request.getContextPath()+"/"+ "request/";
	}
	
	private String retrieveData(PortletPreferences preferences,String dataURL) throws Exception{
		String ajaxData = "";
		String cacheMinutes = (String)preferences.getValue("cacheMinutes",defaultCacheMinutes);
		String isCache = preferences.getValue("isCache", defaultIsCache);
		ajaxData = PortletCacheManager.getOnly().getCachedData(isCache, dataURL, cacheMinutes);
		return ajaxData;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void generate(InfomationsModel infoListModel,String template,StringWriter writer) {
		String encoding = "utf-8";
		try {
        	Configuration cfg = new Configuration();
        	cfg.setTemplateLoader(new StringTemplateLoader(template));  
        	cfg.setEncoding(Locale.getDefault(), encoding);
            cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        	Template temp = cfg.getTemplate("");
        	temp.setEncoding(encoding);
            Map root = new HashMap();
            root.put("model",infoListModel);
            temp.process(root, writer);
            writer.flush();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}
	
	@RenderMode(name = "edit")
	public void edit(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletPreferences preferences = PreferencesHelper.getPublicPreference(request);
		String templateId = preferences.getValue("templateId", null);
		String minHeight = preferences.getValue("minHeight", "400");
		String sortPolicy = preferences.getValue("sortPolicy", InfomationManage.SortPolicy.PublishTimeDesc);
		String queryParamKey = preferences.getValue("queryParamKey", "keyWordsId");
		String queryParamValue = preferences.getValue("queryParamValue", null);
		String infoLinkURL = preferences.getValue("infoLinkURL", null);
		String recCountPerPage = preferences.getValue("recCountPerPage", "20");
		String mainNumCount = preferences.getValue("mainNumCount", "10");
		String sideNumCount = preferences.getValue("sideNumCount", "2");
		String maxCharNumber = preferences.getValue("maxCharNumber", "30");
		String isCache = preferences.getValue("isCache", defaultIsCache);
		String cacheMinutes = preferences.getValue("cacheMinutes", defaultCacheMinutes);
		
		request.setAttribute("templateId", templateId);
		request.setAttribute("minHeight", minHeight);
		request.setAttribute("queryParamKey", queryParamKey);
		request.setAttribute("queryParamValue", queryParamValue);
		request.setAttribute("infoLinkURL", infoLinkURL);
		request.setAttribute("sortPolicy", sortPolicy);
		
		request.setAttribute("recCountPerPage", recCountPerPage);
		request.setAttribute("mainNumCount", mainNumCount);
		request.setAttribute("sideNumCount", sideNumCount);
		request.setAttribute("maxCharNumber", maxCharNumber);
		
		request.setAttribute("isCache", isCache);
		request.setAttribute("cacheMinutes", cacheMinutes);
		
		super.doEdit(request, response);
	}

	@ProcessAction(name = "saveConfig")
	public void saveConfig(ActionRequest request, ActionResponse response)
			throws ReadOnlyException, PortletModeException, ValidatorException,
			IOException, PreferenceException {
		String templateId = request.getParameter("templateId");
		String minHeight = request.getParameter("minHeight");
		String sortPolicy = request.getParameter("sortPolicy");
		String queryParamKey = request.getParameter("queryParamKey");
		String queryParamValue = request.getParameter("queryParamValue");
		
		String infoLinkURL = request.getParameter("infoLinkURL");
		
		String recCountPerPage = request.getParameter("recCountPerPage");
		String mainNumCount = request.getParameter("mainNumCount");
		String sideNumCount = request.getParameter("sideNumCount");
		String maxCharNumber = request.getParameter("maxCharNumber");
		
		String isCache = request.getParameter("isCache");
		String cacheMinutes = request.getParameter("cacheMinutes");
		
		PreferencesWrapper preferWapper = new PreferencesWrapper();		
		preferWapper.setValue("templateId", templateId);
		preferWapper.setValue("minHeight", minHeight);
		preferWapper.setValue("sortPolicy", sortPolicy);
		preferWapper.setValue("queryParamKey", queryParamKey);
		preferWapper.setValue("queryParamValue", queryParamValue);
		
		preferWapper.setValue("infoLinkURL", infoLinkURL);
		
		preferWapper.setValue("recCountPerPage", recCountPerPage);
		preferWapper.setValue("mainNumCount", mainNumCount);
		preferWapper.setValue("sideNumCount", sideNumCount);
		preferWapper.setValue("maxCharNumber", maxCharNumber);
		
		preferWapper.setValue("isCache", isCache);
		preferWapper.setValue("cacheMinutes", cacheMinutes);
		
		PreferencesHelper.savePublicPreferences(request, preferWapper.getPreferences());	
		response.setPortletMode(PortletMode.VIEW);
	}
	
	private List<DataRow> getAuthedRecords(List<DataRow> tempRecords,PortletRequest request){
		List<DataRow> result = new ArrayList<DataRow>();
		Profile profile = (Profile)request.getPortletSession().getAttribute(Profile.PROFILE_KEY,PortletSession.APPLICATION_SCOPE);
		if (profile != null){
			User user = (User)profile.getUser();
			for (int i=0;i < tempRecords.size();i++){
				DataRow row = tempRecords.get(i);
				String authType = row.stringValue("INFO_AUTH_TYPE");
				if (InfomationManage.AuthType.Private.equalsIgnoreCase(authType)){
					String infomatonId = row.stringValue("INFO_ID");
					if (user.containResouce(Resource.Type.Infomation, infomatonId)
							|| "user".equals(user.getUserCode()) || "admin".equals(user.getUserCode())){
						result.add(row);
					}
				}else{
					result.add(row);
				}
			}
		}else{
			for (int i=0;i < tempRecords.size();i++){
				DataRow row = tempRecords.get(i);
				String authType = row.stringValue("INFO_AUTH_TYPE");
				if (InfomationManage.AuthType.Public.equalsIgnoreCase(authType)){
					result.add(row);
				}
			}
		}
		return result;
	}
	
	private String substring(String value ,String lenghtLimit){
		String result = value;
		if (value != null && value.length() > Integer.parseInt(lenghtLimit)){
			result = value.substring(0,Integer.parseInt(lenghtLimit))+"…";
		}
		return result;
	}
}
